์์ง๋ง ๊ฐ๋ ฅํ ํจ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ ์์ํฌ Hyperapp์ ์ดํด๋ณด์ธ์. ํต์ฌ ๊ฐ๋ , ์ฅ์ , ๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ํ๋ ์์ํฌ์์ ๋น๊ต๋ฅผ ์์๋ด ๋๋ค.
Hyperapp: ๋ฏธ๋๋ฉ๋ฆฌ์คํธ ํจ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ ์์ํฌ ์ฌ์ธต ๋ถ์
๋์์์ด ์งํํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ ์์ํฌ ํ๊ฒฝ์์ Hyperapp์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค(UI)๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ๋ฏธ๋๋ฉ๋ฆฌ์คํธ ํจ์ํ ์ ๊ทผ ๋ฐฉ์์ ์ฐพ๋ ๊ฐ๋ฐ์๋ค์๊ฒ ๋งค๋ ฅ์ ์ธ ์ต์ ์ผ๋ก ๋ถ์ํ๊ณ ์์ต๋๋ค. ์ด ๊ธ์์๋ Hyperapp์ ํต์ฌ ๊ฐ๋ , ์ฅ์ , ์ค์ ์์ ๋ฐ ๋ ๋์ ์๋ฐ์คํฌ๋ฆฝํธ ์ํ๊ณ ๋ด์์์ ์์น๋ฅผ ํฌํจํ์ฌ ํฌ๊ด์ ์ผ๋ก ํ๊ตฌํฉ๋๋ค. ๋ค์ํ ์ง๋ฆฌ์ ์์น์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํด Hyperapp์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ ๊ธ๋ก๋ฒ ์ ๊ทผ์ฑ ๋ฐ ํ์งํ์ ๋ํ ๊ณ ๋ ค ์ฌํญ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
Hyperapp์ด๋ ๋ฌด์์ธ๊ฐ?
Hyperapp์ ๋จ์์ฑ๊ณผ ์ฑ๋ฅ์ ์ผ๋์ ๋๊ณ ์ค๊ณ๋ ํ๋ก ํธ์๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ ์์ํฌ์ ๋๋ค. ์ฃผ์ ํน์ง์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์์ ํฌ๊ธฐ: Hyperapp์ ๋ฏฟ์ ์ ์์ ์ ๋๋ก ์์ ํฌ๊ธฐ(์ผ๋ฐ์ ์ผ๋ก 2KB ๋ฏธ๋ง)๋ฅผ ์๋ํ์ฌ ๋ฒ๋ค ํฌ๊ธฐ๋ฅผ ์ต์ํํ๋ ๊ฒ์ด ์ค์ํ ํ๋ก์ ํธ์ ์ด์์ ์ ๋๋ค.
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ: ๋ถ๋ณ์ฑ, ์์ ํจ์, ๊ทธ๋ฆฌ๊ณ UI ๊ฐ๋ฐ์ ๋ํ ์ ์ธ์ ์ ๊ทผ์ ์ฅ๋ คํ๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ํจ๋ฌ๋ค์์ ์ฑํํฉ๋๋ค.
- ๊ฐ์ DOM: Hyperapp์ ๊ฐ์ DOM(Document Object Model)์ ํ์ฉํ์ฌ UI๋ฅผ ํจ์จ์ ์ผ๋ก ์ ๋ฐ์ดํธํ๊ณ , ์ค์ DOM์ ์ง์ ์ ์ธ ์กฐ์์ ์ต์ํํ๋ฉฐ ๋ ๋๋ง ์ฑ๋ฅ์ ์ต์ ํํฉ๋๋ค.
- ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ: ๋ฐ์ดํฐ๊ฐ ํ ๋ฐฉํฅ์ผ๋ก๋ง ํ๋ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ์ถ๋ก ํ๊ณ ๋ฌธ์ ๋ฅผ ๋๋ฒ๊น ํ๊ธฐ๊ฐ ๋ ์ฝ์ต๋๋ค.
- ๋ด์ฅ ์ํ ๊ด๋ฆฌ: Hyperapp์ ๋ด์ฅ ์ํ ๊ด๋ฆฌ ์์คํ ์ ํฌํจํ๊ณ ์์ด ๋ง์ ๊ฒฝ์ฐ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํ์ง ์์ต๋๋ค.
Hyperapp์ ํต์ฌ ๊ฐ๋
1. ์ํ(State)
์ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ํ๋ ๋๋ค. UI๋ฅผ ๋ ๋๋งํ๋ ๋ฐ ํ์ํ ๋ชจ๋ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ๋ถ๋ณ ๊ฐ์ฒด์ ๋๋ค. Hyperapp์์ ์ํ๋ ์ผ๋ฐ์ ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฉ์ธ ํจ์ ๋ด์์ ๊ด๋ฆฌ๋ฉ๋๋ค.
์์:
๊ฐ๋จํ ์นด์ดํฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ์ํ๋ ๋ค์๊ณผ ๊ฐ์ด ํํ๋ ์ ์์ต๋๋ค:
const state = {
count: 0
};
2. ์ก์ (Actions)
์ก์ ์ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ํจ์์ ๋๋ค. ํ์ฌ ์ํ๋ฅผ ์ธ์๋ก ๋ฐ์ ์๋ก์ด ์ํ๋ฅผ ๋ฐํํฉ๋๋ค. ์ก์ ์ ์์ ํจ์์ฌ์ผ ํ๋ฉฐ, ์ด๋ ๋ถ์์ฉ์ด ์์ด์ผ ํ๊ณ ๋์ผํ ์ ๋ ฅ์ ๋ํด ํญ์ ๋์ผํ ์ถ๋ ฅ์ ๋ฐํํด์ผ ํจ์ ์๋ฏธํฉ๋๋ค.
์์:
์นด์ดํฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํด, ์นด์ดํธ๋ฅผ ์ฆ๊ฐ์ํค๊ณ ๊ฐ์์ํค๋ ์ก์ ์ ์ ์ํ ์ ์์ต๋๋ค:
const actions = {
increment: state => ({ count: state.count + 1 }),
decrement: state => ({ count: state.count - 1 })
};
3. ๋ทฐ(View)
๋ทฐ๋ ํ์ฌ ์ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก UI๋ฅผ ๋ ๋๋งํ๋ ํจ์์ ๋๋ค. ์ํ์ ์ก์ ์ ์ธ์๋ก ๋ฐ์ UI์ ๊ฐ์ DOM ํํ์ ๋ฐํํฉ๋๋ค.
Hyperapp์ `h`(hyperscript์ ์ฝ์)๋ผ๋ ๊ฒฝ๋ ๊ฐ์ DOM ๊ตฌํ์ ์ฌ์ฉํฉ๋๋ค. `h`๋ ๊ฐ์ DOM ๋ ธ๋๋ฅผ ์์ฑํ๋ ํจ์์ ๋๋ค.
์์:
์ฐ๋ฆฌ ์นด์ดํฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ทฐ๋ ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค:
const view = (state, actions) => (
<div>
<h1>Count: {state.count}</h1>
<button onclick={actions.decrement}>-</button>
<button onclick={actions.increment}>+</button>
</div>
);
4. `app` ํจ์
`app` ํจ์๋ Hyperapp ์ ํ๋ฆฌ์ผ์ด์ ์ ์ง์ ์ ์ ๋๋ค. ๋ค์ ์ธ์๋ค์ ๋ฐ์ต๋๋ค:
- `state`: ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๊ธฐ ์ํ.
- `actions`: ์ํ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์๋ ์ก์ ๋ค์ ํฌํจํ๋ ๊ฐ์ฒด.
- `view`: UI๋ฅผ ๋ ๋๋งํ๋ ๋ทฐ ํจ์.
- `node`: ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ง์ดํธ๋ DOM ๋ ธ๋.
์์:
๋ชจ๋ ๊ฒ์ ํ๋๋ก ๋ฌถ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
import { h, app } from "hyperapp";
const state = {
count: 0
};
const actions = {
increment: state => ({ count: state.count + 1 }),
decrement: state => ({ count: state.count - 1 })
};
const view = (state, actions) => (
<div>
<h1>Count: {state.count}</h1>
<button onclick={actions.decrement}>-</button>
<button onclick={actions.increment}>+</button>
</div>
);
app(state, actions, view, document.getElementById("app"));
Hyperapp ์ฌ์ฉ์ ์ด์
- ์ฑ๋ฅ: Hyperapp์ ์์ ํฌ๊ธฐ์ ํจ์จ์ ์ธ ๊ฐ์ DOM ๊ตฌํ์ ํนํ ๋ฆฌ์์ค๊ฐ ์ ํ๋ ์ฅ์น ๋ฐ ๋คํธ์ํฌ์์ ๋ฐ์ด๋ ์ฑ๋ฅ์ ๊ธฐ์ฌํฉ๋๋ค. ์ด๋ ๋์ญํญ์ด ์ ํ์ ์ด๊ฑฐ๋ ์ค๋๋ ํ๋์จ์ด๋ฅผ ์ฌ์ฉํ๋ ์ง์ญ์ ์ฌ์ฉ์์๊ฒ ํนํ ์ ์ฉํฉ๋๋ค.
- ๋จ์์ฑ: ํ๋ ์์ํฌ์ ๋ฏธ๋๋ฉํ ๋์์ธ๊ณผ ํจ์ํ ์ ๊ทผ ๋ฐฉ์์ ๋ฐฐ์ฐ๊ณ ์ฌ์ฉํ๊ธฐ ์ฌ์ ์ ๊ท ๊ฐ๋ฐ์์ ํ์ต ๊ณก์ ์ ์ค์ด๊ณ ์ฝ๋ ์ ์ง ๊ด๋ฆฌ๋ฅผ ๋จ์ํํฉ๋๋ค.
- ์ ์ง๋ณด์์ฑ: ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ๊ณผ ๋ถ๋ณ ์ํ๋ ์์ธก ๊ฐ๋ฅํ ๋์๊ณผ ์ฌ์ด ๋๋ฒ๊น ์ ์ด์งํ์ฌ ์ ์ง๋ณด์๊ฐ ๋ ์ฉ์ดํ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๋ง๋ญ๋๋ค.
- ์ ์ฐ์ฑ: Hyperapp์ ์์ ํฌ๊ธฐ๋ ๊ธฐ์กด ํ๋ก์ ํธ์ ์ฝ๊ฒ ํตํฉํ๊ฑฐ๋ ๋ ํฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ฑ ์์๋ก ์ฌ์ฉํ ์ ์๊ฒ ํฉ๋๋ค.
- ์ ๊ทผ์ฑ: ํจ์ํ ์ ๊ทผ ๋ฐฉ์๊ณผ ๋ช ํํ ๊ด์ฌ์ฌ ๋ถ๋ฆฌ๋ ์ ๊ทผ์ฑ ๋์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋๋ ๊ฒ์ ์ด์งํ๋ฉฐ, ์ด๋ WCAG ๊ฐ์ด๋๋ผ์ธ์ ์ค์ํ๋ ๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๊ฐ๋ฐ์์๊ฒ ๋งค์ฐ ์ค์ํฉ๋๋ค.
Hyperapp๊ณผ ๋ค๋ฅธ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ ์์ํฌ ๋น๊ต
Hyperapp์ React, Vue, Angular์ ๊ฐ์ ๋ค๋ฅธ ์ธ๊ธฐ ์๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ ์์ํฌ์ ์์ฃผ ๋น๊ต๋ฉ๋๋ค. ๊ฐ๋ตํ ๋น๊ต๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- React: React๋ Hyperapp๋ณด๋ค ๋ ํฌ๊ณ ๊ธฐ๋ฅ์ด ํ๋ถํ ํ๋ ์์ํฌ์ ๋๋ค. ๋ ํฐ ์ํ๊ณ์ ๊ด๋ฒ์ํ ์ปค๋ฎค๋ํฐ ์ง์์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋ React์ ๋ณต์ก์ฑ์ ์ ๊ท ๊ฐ๋ฐ์์๊ฒ ์ง์ ์ฅ๋ฒฝ์ด ๋ ์ ์์ต๋๋ค.
- Vue: Vue๋ ์ฌ์ฉํ๊ธฐ ์ฝ๊ณ ์๋งํ ํ์ต ๊ณก์ ์ผ๋ก ์์ฃผ ์นญ์ฐฌ๋ฐ๋ ์ ์ง์ ํ๋ ์์ํฌ์ ๋๋ค. ๊ฐ๋ ฅํ๋ฉด์๋ ๋ฐฐ์ฐ๊ธฐ ์ฌ์ด ํ๋ ์์ํฌ๋ฅผ ์ํ๋ ๊ฐ๋ฐ์์๊ฒ ์ข์ ์ต์ ์ ๋๋ค. Hyperapp์ Vue๋ณด๋ค ๋ ์๊ณ ๊ฐ๋ณ์ต๋๋ค.
- Angular: Angular๋ Google์์ ๊ฐ๋ฐํ ํฌ๊ด์ ์ธ ํ๋ ์์ํฌ์ ๋๋ค. ํฌ๊ณ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ์ ์ข์ ์ต์ ์ ๋๋ค. ๊ทธ๋ฌ๋ Angular๋ ๋ณต์ก์ฑ๊ณผ ๊ฐํ๋ฅธ ํ์ต ๊ณก์ ๋๋ฌธ์ ์๊ท๋ชจ ํ๋ก์ ํธ์๋ ๋ถ๋ด์ค๋ฌ์ธ ์ ์์ต๋๋ค.
Hyperapp์ ๊ทน๋์ ๋ฏธ๋๋ฉ๋ฆฌ์ฆ๊ณผ ํจ์ํ ํน์ฑ์ผ๋ก ์ฐจ๋ณํ๋ฉ๋๋ค. ๋ด์ฅ ์์คํ , ๋ชจ๋ฐ์ผ ์ ํ๋ฆฌ์ผ์ด์ ๋๋ ์ ํ๋ ๋ฆฌ์์ค๋ฅผ ๊ฐ์ง ์น ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๊ฐ์ด ํฌ๊ธฐ์ ์ฑ๋ฅ์ด ๊ฐ์ฅ ์ค์ํ ์๋๋ฆฌ์ค์์ ๋ฐ์ด๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, Hyperapp์ ์ํ๋ฆฌ์นด๋ ๋จ์๋ฉ๋ฆฌ์นด ์ผ๋ถ ์ง์ญ๊ณผ ๊ฐ์ด ์ธํฐ๋ท ์๋๊ฐ ๋๋ฆฐ ์ง์ญ์ ์น์ฌ์ดํธ์์ ์ด๊ธฐ ๋ก๋ฉ ์๊ฐ์ ์ค์ด๋ ๊ฒ์ด ์ฌ์ฉ์ ๊ฒฝํ์ ์ค์ํ ๊ฒฝ์ฐ, ์ํธ์์ฉ ์์๋ฅผ ๊ฐ๋ฐํ๊ธฐ ์ํ ํ๋ฅญํ ์ ํ์ด ๋ ์ ์์ต๋๋ค.
Hyperapp ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค์ ์์
Hyperapp์ ๊ฐ๋จํ ์ํธ์์ฉ ์ปดํฌ๋ํธ๋ถํฐ ๋ณต์กํ ๋จ์ผ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์ (SPA)์ ์ด๋ฅด๊ธฐ๊น์ง ๋ค์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ๋ช ๊ฐ์ง ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๊ฐ๋จํ ์นด์ดํฐ: ์์ ๋ณด์ฌ๋๋ฆฐ ๋ฐ์ ๊ฐ์ด, Hyperapp์ ์นด์ดํฐ, ํ ๊ธ, ๋ฒํผ๊ณผ ๊ฐ์ ๊ฐ๋จํ ์ํธ์์ฉ ์์๋ฅผ ๋ง๋๋ ๋ฐ ๋งค์ฐ ์ ํฉํฉ๋๋ค.
- ํ ์ผ ๋ชฉ๋ก: Hyperapp์ ์ฌ์ฉํ์ฌ ์์ ์ถ๊ฐ, ์ญ์ , ์๋ฃ ํ์์ ๊ฐ์ ๊ธฐ๋ฅ์ ๊ฐ์ถ ๊ธฐ๋ณธ ํ ์ผ ๋ชฉ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
- ๊ฐ๋จํ ๊ณ์ฐ๊ธฐ: Hyperapp์ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ๊ณ ๊ณ์ฐ์ ์ํํ๋ ๊ธฐ๋ณธ ๊ณ์ฐ๊ธฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ญ๋๋ค.
- ๋ฐ์ดํฐ ์๊ฐํ: Hyperapp์ ๊ฐ์ DOM์ ์ฐจํธ์ ๊ทธ๋ํ๋ฅผ ํจ์จ์ ์ผ๋ก ์ ๋ฐ์ดํธํ๋ฏ๋ก ๋์๋ณด๋๋ ๋ณด๊ณ ๋๊ตฌ์ ์ ์ฉํฉ๋๋ค. D3.js์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ Hyperapp๊ณผ ์ฝ๊ฒ ํตํฉ๋ ์ ์์ต๋๋ค.
Hyperapp ๊ฐ๋ฐ์ ์ํ ๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋๋ ํ์งํ, ๊ตญ์ ํ, ์ ๊ทผ์ฑ๊ณผ ๊ฐ์ ์์๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค.
1. ํ์งํ (l10n)
ํ์งํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ๋ก์ผ์ผ์ด๋ ์ง์ญ์ ๋ง๊ฒ ์กฐ์ ํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์ฌ๊ธฐ์๋ ํ ์คํธ ๋ฒ์ญ, ๋ ์ง ๋ฐ ์ซ์ ์์ ์ง์ , ๋ค๋ฅธ ์ฐ๊ธฐ ๋ฐฉํฅ์ ์์ฉํ๊ธฐ ์ํ ๋ ์ด์์ ์กฐ์ ๋ฑ์ด ํฌํจ๋ฉ๋๋ค.
์์:
๋ ์ง๋ฅผ ํ์ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๊ฐํด ๋ด ์๋ค. ๋ฏธ๊ตญ์์๋ ๋ ์ง๊ฐ ์ผ๋ฐ์ ์ผ๋ก MM/DD/YYYY ํ์์ผ๋ก ํ์๋์ง๋ง, ์ ๋ฝ์์๋ ์ข ์ข DD/MM/YYYY ํ์์ผ๋ก ํ์๋ฉ๋๋ค. ํ์งํ๋ ์ฌ์ฉ์ ๋ก์ผ์ผ์ ๋ง๊ฒ ๋ ์ง ํ์์ ์กฐ์ ํ๋ ์์ ์ ํฌํจํฉ๋๋ค.
Hyperapp์๋ ๋ด์ฅ๋ ํ์งํ ์ง์์ด ์์ง๋ง, `i18next`๋ `lingui`์ ๊ฐ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฝ๊ฒ ํตํฉํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฒ์ญ์ ๊ด๋ฆฌํ๊ณ ์ฌ์ฉ์ ๋ก์ผ์ผ์ ๋ฐ๋ผ ๋ฐ์ดํฐ๋ฅผ ์์ ์ง์ ํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
2. ๊ตญ์ ํ (i18n)
๊ตญ์ ํ๋ ๋ค๋ฅธ ์ง์ญ์ ๋ง๊ฒ ์ฝ๊ฒ ํ์งํํ ์ ์๋๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๊ณํ๊ณ ๊ฐ๋ฐํ๋ ๊ณผ์ ์ ๋๋ค. ์ฌ๊ธฐ์๋ ์ฝ๋์์ ํ ์คํธ๋ฅผ ๋ถ๋ฆฌํ๊ณ , ํ ์คํธ ์ธ์ฝ๋ฉ์ ์ ๋์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉฐ, ๋ค๋ฅธ ์ธ์ด์ ๋ฌธํ์ ๋ง๊ฒ UI๋ฅผ ์กฐ์ ํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ๋ ๊ฒ์ด ํฌํจ๋ฉ๋๋ค.
๋ชจ๋ฒ ์ฌ๋ก:
- ์ ๋์ฝ๋ ์ฌ์ฉ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ๊ด๋ฒ์ํ ๋ฌธ์๋ฅผ ์ง์ํ๋๋ก ํ ์คํธ ์ธ์ฝ๋ฉ์ ์ ๋์ฝ๋(UTF-8)๋ฅผ ์ฌ์ฉํ๋์ง ํ์ธํ์ธ์.
- ์ฝ๋์์ ํ ์คํธ ๋ถ๋ฆฌ: ๋ชจ๋ ํ ์คํธ๋ฅผ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์ ํ๋์ฝ๋ฉํ๋ ๋์ ์ธ๋ถ ๋ฆฌ์์ค ํ์ผ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ์ธ์.
- ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ(RTL) ์ธ์ด ์ง์: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๋์ด ๋ฐ ํ๋ธ๋ฆฌ์ด์ ๊ฐ์ RTL ์ธ์ด๋ฅผ ์ฒ๋ฆฌํ ์ ์๋์ง ํ์ธํ์ธ์. ์ฌ๊ธฐ์๋ ๋ ์ด์์์ ๋ฏธ๋ฌ๋งํ๊ณ ํ ์คํธ ์ ๋ ฌ์ ์กฐ์ ํ๋ ๊ฒ์ด ํฌํจ๋ ์ ์์ต๋๋ค.
- ๋ฌธํ์ ์ฐจ์ด ๊ณ ๋ ค: ์์ ์์ง, ์ด๋ฏธ์ง, ์์ฌ์ํต ์คํ์ผ๊ณผ ๊ฐ์ ์์ญ์์์ ๋ฌธํ์ ์ฐจ์ด๋ฅผ ์ธ์งํ์ธ์.
3. ์ ๊ทผ์ฑ (a11y)
์ ๊ทผ์ฑ์ ์ฅ์ ๊ฐ ์๋ ์ฌ๋๋ค์ด ์ฌ์ฉํ ์ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๊ณํ๊ณ ๊ฐ๋ฐํ๋ ๊ดํ์ ๋๋ค. ์ฌ๊ธฐ์๋ ์ด๋ฏธ์ง์ ๋ํ ๋์ฒด ํ ์คํธ ์ ๊ณต, ํค๋ณด๋๋ฅผ ์ฌ์ฉํ์ฌ UI๋ฅผ ํ์ํ ์ ์๋๋ก ๋ณด์ฅ, ์ค๋์ค ๋ฐ ๋น๋์ค ์ฝํ ์ธ ์ ๋ํ ์บก์ ์ ๊ณต ๋ฑ์ด ํฌํจ๋ฉ๋๋ค.
WCAG ๊ฐ์ด๋๋ผ์ธ:
์น ์ฝํ ์ธ ์ ๊ทผ์ฑ ๊ฐ์ด๋๋ผ์ธ(WCAG)์ ์น ์ฝํ ์ธ ๋ฅผ ๋ ์ ๊ทผํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค๊ธฐ ์ํ ๊ตญ์ ํ์ค ์งํฉ์ ๋๋ค. ์ด ๊ฐ์ด๋๋ผ์ธ์ ๋ฐ๋ฅด๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ด ๊ด๋ฒ์ํ ์ฅ์ ๋ฅผ ๊ฐ์ง ์ฌ๋๋ค์ด ์ฌ์ฉํ ์ ์๋๋ก ๋ณด์ฅํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
Hyperapp๊ณผ ์ ๊ทผ์ฑ:
Hyperapp์ ํจ์ํ ์ ๊ทผ ๋ฐฉ์๊ณผ ๋ช ํํ ๊ด์ฌ์ฌ ๋ถ๋ฆฌ๋ ์ ๊ทผ์ฑ ๋์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ ์ฝ๊ฒ ๋ง๋๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ์ ๊ทผ์ฑ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๊ณ ์ ์ ํ HTML ์๋งจํฑ ์์๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ Hyperapp ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ชจ๋ ์ฌ๋์ด ์ฌ์ฉํ ์ ์๋๋ก ๋ณด์ฅํ ์ ์์ต๋๋ค.
๊ณ ๊ธ Hyperapp ๊ธฐ์
1. ํจ๊ณผ(Effects)
ํจ๊ณผ๋ API ํธ์ถ์ด๋ DOM ์ง์ ์ ๋ฐ์ดํธ์ ๊ฐ์ ๋ถ์์ฉ์ ์ํํ๋ ํจ์์ ๋๋ค. Hyperapp์์ ํจ๊ณผ๋ ์ผ๋ฐ์ ์ผ๋ก ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๊ฑฐ๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํธ ์์ฉํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
์์:
const FetchData = (dispatch, data) => {
fetch(data.url)
.then(response => response.json())
.then(data => dispatch(data.action, data));
};
const actions = {
fetchData: (state, data) => [state, [FetchData, data]]
};
2. ๊ตฌ๋ (Subscriptions)
๊ตฌ๋ ์ ์ฌ์ฉํ๋ฉด ์ธ๋ถ ์ด๋ฒคํธ๋ฅผ ๊ตฌ๋ ํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค. ์ด๋ ํ์ด๋จธ ํฑ, WebSocket ๋ฉ์์ง ๋๋ ๋ธ๋ผ์ฐ์ ์์น ๋ณ๊ฒฝ๊ณผ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
์์:
const Clock = (dispatch, data) => {
const interval = setInterval(() => dispatch(data.action), 1000);
return () => clearInterval(interval);
};
const subscriptions = state => [
state.isRunning && [Clock, { action: actions.tick }]
];
3. TypeScript์ ํจ๊ป ์ฌ์ฉํ๊ธฐ
Hyperapp์ TypeScript์ ํจ๊ป ์ฌ์ฉํ์ฌ ์ ์ ํ์ดํ์ ์ ๊ณตํ๊ณ ์ฝ๋ ์ ์ง๋ณด์์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. TypeScript๋ ๊ฐ๋ฐ ๊ณผ์ ์ด๊ธฐ์ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ณ ์ฝ๋ ๋ฆฌํฉํ ๋ง์ ๋ ์ฝ๊ฒ ๋ง๋๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
Hyperapp์ ๋ฏธ๋๋ฉ๋ฆฌ์ฆ, ์ฑ๋ฅ, ๊ทธ๋ฆฌ๊ณ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์์น์ ๋งค๋ ฅ์ ์ธ ์กฐํฉ์ ์ ๊ณตํฉ๋๋ค. ์์ ํฌ๊ธฐ์ ํจ์จ์ ์ธ ๊ฐ์ DOM์ ๋์ญํญ์ด ์ ํ์ ์ด๊ฑฐ๋ ์ค๋๋ ํ๋์จ์ด๋ฅผ ์ฌ์ฉํ๋ ์ง์ญ์ ์ํ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๊ฐ์ด ์ฑ๋ฅ์ด ์ค์ํ ํ๋ก์ ํธ์ ํ๋ฅญํ ์ ํ์ด ๋ฉ๋๋ค. React๋ Angular์ ๊ฐ์ ๋ํ ํ๋ ์์ํฌ์ ๊ด๋ฒ์ํ ์ํ๊ณ๋ ์์ ์ ์์ง๋ง, ๊ทธ ๋จ์์ฑ๊ณผ ์ ์ฐ์ฑ์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ๊ฐ๋ณ๊ณ ํจ์จ์ ์ธ ์๋ฃจ์ ์ ์ฐพ๋ ๊ฐ๋ฐ์์๊ฒ ๊ท์คํ ๋๊ตฌ๊ฐ ๋ฉ๋๋ค.
ํ์งํ, ๊ตญ์ ํ, ์ ๊ทผ์ฑ๊ณผ ๊ฐ์ ๊ธ๋ก๋ฒ ์์๋ฅผ ๊ณ ๋ คํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ Hyperapp์ ํ์ฉํ์ฌ ๋ค์ํ ๊ธ๋ก๋ฒ ์ฌ์ฉ์์๊ฒ ์ ์ฉํ๊ณ ์ ๊ทผ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ์น์ด ๊ณ์ ์งํํจ์ ๋ฐ๋ผ, ๋จ์์ฑ๊ณผ ์ฑ๋ฅ์ ๋ํ Hyperapp์ ์ด์ ์ ํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ์์ด ์ ์ ๋ ์ ์ ํ ์ ํ์ด ๋ ๊ฒ์ ๋๋ค.